package utils

import archer.common.exceptions.ClassPathAssetsNotFoundException
import org.apache.commons.io.IOUtils

import scala.collection.JavaConverters._
import scala.concurrent.{ ExecutionContext, Future }
import scala.language.higherKinds
import cats.implicits._

import scala.util.Try

trait ClassPathUtil extends ArcherHelper {

  def strFromClassPath(path: String)(
    implicit
    ec: ExecutionContext): V.ResultT[String] = {
    val nullCatch = commonCatch.withErrorHandler { msg =>
      {
        case ne: NullPointerException =>
          val ex = new ClassPathAssetsNotFoundException(path)
          ex.initCause(ex)
          logger.error(ex.getMessage, ex)
          ErrorResult(ex.getMessage)
      }
    }
    val stream = getClass.getResourceAsStream(path)
    nullCatch {
      Future {
        IOUtils.readLines(stream, "utf-8").asScala.mkString("{~n}")
      }.andThen {
        case _ =>
          if (stream != null) {
            Future {
              Try {
                stream.close()
              }
            }
          }
      }
    }
    /*.attemptT.leftMap {
      case ne: NullPointerException =>
        val ex = new ClassPathAssetsNotFoundException(path)
        ex.initCause(ex)
        logger.error(ex.getMessage, ex)
        ErrorResult(ex.getMessage)
    }*/
  }

  def strFromClassPathOrThrow(path: String)(
    implicit
    ec: ExecutionContext): String = {
    val stream = getClass.getResourceAsStream(path)
    try {
      IOUtils.readLines(stream, "utf-8").asScala.mkString("{~n}")
    } catch {
      case ne: NullPointerException =>
        val ex = new ClassPathAssetsNotFoundException(path)
        ex.initCause(ne)
        logger.error(ex.getMessage, ex)
        throw ex
    } finally {
      if (stream != null) {
        Try {
          stream.close()
        }
      }
    }

  }

}

object ClassPathUtil extends ClassPathUtil
